//CUBELIB.JS

/*************************************************************/
/*
 *

### FORM

Element.getFormItemsName()
    Unique list of fields name

Element.fillFormItems(input,fixdata)
    Fill a form with data
    * input   [JSON] -> JSON of data
    * fixdata [BOOL] -> makes input as default data (reset will change to these)

Element.fixFormItems()
    Makes current data as default data (reset will change to these)

Element.getFormItems(formdata)
    Get form fields and return a JSON with key=field.name and value=field.value
    * formdata [STRING] -> default : returns JSON
                           "formdata" : returns FORMDATA
                           "urlencoded" : return URLENCODED

### SELECT



String.toElement()
    Makes an Array of Element from a string

*/
/*************************************************************/
/*************************************************************/
(function(){
var empty = function(){},
	progressSupport = ('onprogress' in new Browser.Request);

Request.MULTIPART = new Class({
	Extends: Request,

	initialize: function(options) {
		this.parent(options);
        this.options.urlEncoded = false;
        this.options.emulation = true;
	},

	send: function(options) {
		if (!this.check(options)) return this;

		this.options.isSuccess = this.options.isSuccess || this.isSuccess;
		this.running = true;

        if (instanceOf(options,FormData)) options = {data: options}; //NEW

        //SOME LINES DELETED

		var old = this.options;
		options = Object.append({data: old.data, url: old.url, method: old.method}, options);
		var data = options.data, url = String(options.url), method = options.method.toLowerCase();

        //DATA LINES DELETED

		if (this.options.urlEncoded && ['post', 'put'].contains(method)){
			var encoding = (this.options.encoding) ? '; charset=' + this.options.encoding : '';
            //DELETE EDIT TO CONTENT-TYPE
		}

		if (!url) url = document.location.pathname;

		var trimPosition = url.lastIndexOf('/');
		if (trimPosition > -1 && (trimPosition = url.indexOf('#')) > -1) url = url.substr(0, trimPosition);

		if (this.options.noCache)
			url += (url.contains('?') ? '&' : '?') + String.uniqueID();

        //DATA LINES DELETED

		var xhr = this.xhr;
		if (progressSupport){
			xhr.onloadstart = this.loadstart.bind(this);
			//xhr.onprogress = this.progress.bind(this);
            xhr.upload.onprogress = this.progress.bind(this);
		}

		xhr.open(method.toUpperCase(), url, this.options.async, this.options.user, this.options.password);
		if (this.options.user && 'withCredentials' in xhr) xhr.withCredentials = true;

		xhr.onreadystatechange = this.onStateChange.bind(this);

		Object.each(this.headers, function(value, key){
			try {
				xhr.setRequestHeader(key, value);
			} catch (e){
				this.fireEvent('exception', [key, value]);
			}
		}, this);

		this.fireEvent('request');
		xhr.send(data);
		if (!this.options.async) this.onStateChange();
		if (this.options.timeout) this.timer = this.timeout.delay(this.options.timeout, this);
		return this;
    }


});
})();

/* EXTEND ELEMENT */
Element.implement({
    //implement show
    fancyShow: function() {
        this.fade('in');
    },
    //implement hide
    fancyHide: function() {
        this.fade('out');
    },
    setFocus: function(index) {
        this.setAttribute('tabIndex',index || 0);
        this.focus();
    }
});

/* SELECT */
Element.implement({
    getSelectValues: function(property) {
        if (this.get('tag')!='select') return null;
        var el = this;
        if (!property) property = 'value';
        
        var options = [];
        Array.forEach(el.options, function(option) {
            if (option.get('selected'))
               options.push(option.get(property));
        });
        value = options;
        return value;
    },
    setSelectValues: function(values,property) {
        if (this.get('tag')!='select') return;
        var el = this;
        if (!property) property = 'value';

        Array.forEach(el.options, function(option) {
            try {
            option.removeProperty('selected');
            } catch(e) {}
        });

        Array.forEach(el.options, function(option) {
            var value = option.get(property);
            if (property=='value') value = parseInt(value);
            if (typeOf(values)=='array') {
                if (values.contains(value))
                   option.set('selected',true);
            } else {
               option.set('selected',true);
            }
        });
        return;
    }
    
});

Element.implement({
    getFormItemsName: function() {
        if (this.get('tag')!='form') return []; //is a form?
        var form = this;
        var items = [];
        new Elements(form.elements).forEach(function(el) {
            if ((el.name) && (items.indexOf(el.name)==-1)) {
                items.push(el.name);
            }
        });
    },

    getFormItemsDom: function() {
        if (this.get('tag')!='form') return []; //is a form?
        var form = this;
        return form.getElements('input:not([type=button],[type=reset],[type=submit]), textarea, select')
    },

    fillFormItems: function(input,fixdata) {
        if (this.get('tag')!='form') return []; //is a form?

        var data = Object.clone(input);
        if (typeof(input)=='string') data = JSON.parse(input);

        var form = this;
        new Elements(form.elements).forEach(function(el) {
            key = el.get('name');
            if (typeOf(data[key])=='array') {
                value = data[key].shift(); //support array qs
            } else {
                value = data[key];
            }

            //if (value) {
                switch(el.get('type')) {
                    case 'checkbox':
                    case 'radio':
                        setvalue = (value == el.get('value'))
                        if (setvalue) {
                            el.setProperty('checked',true);
                            if (fixdata) el.setAttribute('checked',true);
                        } else { 
                            el.removeProperty('checked');
                            if (fixdata) el.removeAttribute('checked');
                        }
                        break;
                    case 'select-one':
                        el.setProperty('value',value);
                        if (fixdata) el.setAttribute('value',value);
                        new Elements(el.options).forEach(function(el) {
                            setvalue = (value == el.get('value'))
                            if (setvalue) {
                                el.set('selected',true); 
                                if (fixdata) el.setAttribute('selected',true);
                            } else { 
                                el.removeProperty('selected');
                                if (fixdata) el.removeAttribute('selected');
                            }
                        });
                        break;
                    default:
                        if (value) {
                            el.setProperty('value',value);
                            if (fixdata) el.setAttribute('value',value);
                        }
                }
            //}
        });
        return;

    },

    fixFormItems: function() {
        if (this.get('tag')!='form') return []; //is a form?

        var form = this;
        new Elements(form.elements).forEach(function(el) {
            switch(el.get('type')) {
                case 'checkbox':
                case 'radio':
                    if (el.getProperty('checked')) el.setAttribute('checked',true);
                    else el.removeAttribute('checked');
                    break;
                case 'select-one':
                    new Elements(el.options).forEach(function(el) {
                        if (el.getProperty('selected')) el.setAttribute('selected',true);
                        else el.removeAttribute('selected');
                    });
                    break;
                default:
                    el.setAttribute('value',el.getProperty('value') || '');
            }
        });
        return;
    },

    getFormItems: function(format) {
        if (this.get('tag')!='form') return []; //is a form?

        var data = {};
        var form = this;

        new Elements(form.elements).forEach(function(el){
            append = true;
            fill=false;
            value=el.get('value');
            key=el.get('name');
            switch(el.get('type')) {
                case 'checkbox':
                case 'radio':
                    if (el.get('checked')) fill=true;
                    if (el.get('type')=='radio') append = false;
                    break;
                case 'file':
                    var files = [];
                    Array.forEach(el.files, function(file) {
                        files.push(file);
                    }); 
                    switch (files.length) {
                        case 0: files=null; break;
                        case 1: files=files[0]; break;
                    }
                    value = files;
                    append=false;
                    fill=true;
                    break;
                default:
                    fill=true;
            }
            if (el.get('tag')=='select') {
                value = el.getSelectValues();
                switch (value.length) {
                    case 0: value=null; break;
                    case 1: value=value[0]; break;
                }
                append=false;
                fill=true;
            }

            if (fill && key) {
                if (append) {
                    if (data.hasOwnProperty(key)) {
                        if (typeOf(data[key])!='array')
                            data[key] = [data[key]]; //makes an array
                        data[key].push(value);
                    } else data[key] = value;
                } else data[key] = value;
            }
        });
        switch(format) {
            case 'formdata':
                var formdata = new FormData();
                for (var key in data) {
                    value = data[key];
                    if (typeOf(value)=='array') {
                        Array.forEach(value, function(v) {
                            formdata.append(key,v);
                        });
                    }else{
                        formdata.append(key,value);
                    }
                }
                data = formdata;
                break;
            case 'urlencoded':
                var urlencoded = [];
                for (var key in data) {
                    value = data[key];
                    if (typeOf(value)=='array') {
                        Array.forEach(value, function(v) {
                            urlencoded.push(key+'='+escape(v));
                        });
                    }else {
                        if(value!=null) urlencoded.push(key+'='+escape(value));
                    }
                }
                data = Array.join(urlencoded,'&');
                break;
        }
        return data;
    }
});

String.implement({
    toElement: function() {
        var injector = Element('div',{'html':this});
        var children = injector.getChildren().clone();
        injector.destroy();
        return children;
    }
});

Number.implement({
    humanBytes: function() {
        var m = ['B','kB','MB','GB','TB','PB','EB','ZB','YB'];
        var limit = 1024;
        var r = this;
        var exp = 0;

        while(r > limit) {
            r = r/1024.0;
            exp+=1;
        }

        return r.toFixed(2)+' '+m[exp];
    }
});


/*************************************************************/
/*************************************************************/
/*************************************************************/

function activeDatepicker(elements) {
    if (!elements) elements = $$(".datepicker")

    elements.each(function(el) {
        // crea l'oggetto hidden _value con il valore ISO
        debug = false
        el_id = el.get('id');
        el_name = el.get('name');
        el.set('name',el_name+'_label');
        var inputValue = Element('input',{'name':el_name,'type':(debug?'text':'hidden')});
        if (el_id) {
            inputValue.set('id',el_id);
            el.set('id',el_id+'_label');
        }
        inputValue.inject(el,'after');

        hastime = el.hasClass('timepicker');

        // crea il datepicker
        options = { timePicker:hastime, 
                    positionOffset: {x: 5, y: 0},
                    pickerClass: 'datepicker_dashboard',
                    useFadeInOut: !Browser.ie,
                    onSelect: function(date) {
                        inputValue.set('value', date.format(hastime?"iso8601":'%Y-%m-%d'));
                    },
                    onOpen: function() { 
                        if (el.get('readonly')) { this.hide(); }
                    },
                  }
        var dp = new Picker.Date(el, options);

        dp.getInputDate(el);
        el.setAttribute('value',dp.date.format(hastime?'%x %X':'%x')); //use setAttribute to edit the value in DOM (needed to reset)
        inputValue.setAttribute('value',dp.date.format(hastime?'iso8601':'%Y-%m-%d')); //use setAttribute to edit the value in DOM (needed to reset)
    });

}

/* TABLES */
/* example
<span class="filter-placeholder"></span> <-- here the search input
<table class="filterable sortable">
</table>
*/

function activeSortable() {
    // Sortable
     HtmlTable.defineParsers({
         bytes: {
             match: /\d (k|M|G|T|P)?B/,
             convert: function() {
                 var span = this.getElement('span');
                 if(span) {
                     return span.get('text').toInt();
                 } else {
                     return 0;
                 }
             },
             number: true
         }
         });
    $$('.sortable').each(function(table) {  
        new HtmlTable(table, {
            sortable: true,
            sortIndex: null,
            classZebra: 'row1',
            zebra: true,
        }); 
    });
}

function activeFilterable() {
   //Filterable
    new FilterTable({
        filterClass: 'filterable',
        placeholder: $('filter-placeholder'),
        label: '',
        placeholder_text: 'filter...',
        type: 'text'
    });
}

/*************************************************************/
/*************************************************************/
/*************************************************************/

/* MODAL WINDOWS */
/* example code
<div id="myid" class="modal"> <-- this is modal
   <a class="close">X</a> <-- this is its close button
</div>
*/

var modal = ''; /* last modal opened */
function modalInit() {
        $('modalbg').hide();
        $$('.modal').hide();
        $$('.modal a.close').addEvent("click", function(e) { modalClose(); return false; });
}

function modalOpen(el,bgclose,html) {
        if (!el) return;
        if (bgclose) $('modalbg').addEvent("click", function(e) { modalClose(); });
        if (html) el.getElement('.content').set({'html':html});
        $('modalbg').show();
        el.show();
        modal = el;
}

function modalClose() {
        modal.hide();
        $('modalbg').hide();
        $('modalbg').removeEvents("click");
}

/*************************************************************/
/*************************************************************/
/*************************************************************/
